package com.demo.studentmanager.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.demo.studentmanager.dto.UserAddDto;
import com.demo.studentmanager.dto.UserListDto;
import com.demo.studentmanager.dto.UserUpdDto;
import com.demo.studentmanager.entity.User;
import com.demo.studentmanager.exception.BizException;
import com.demo.studentmanager.result.Result;
import com.demo.studentmanager.result.ResultCode;
import com.demo.studentmanager.service.IRoleService;
import com.demo.studentmanager.service.IUserService;
import com.demo.studentmanager.util.CheckEntityUtil;
import com.demo.studentmanager.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

/**
 * @author wx
 */
@Api(tags = "用户模块")
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private IUserService userService;

    @Resource
    private IRoleService roleService;

    @ApiOperation(value = "用户登陆")
    @PostMapping("/login")
    Result login(@NotNull @RequestParam String id, @NotNull @RequestParam String password) {
        Subject subject = SecurityUtils.getSubject();
        //清除缓存
        subject.logout();

        if (!subject.isAuthenticated()) {

            UsernamePasswordToken token = new UsernamePasswordToken(id, password);

            try {
                subject.login(token);
            } catch (UnknownAccountException e) {
                throw new BizException(ResultCode.USER_ACCOUNT_NOT_EXIST);
            } catch (IncorrectCredentialsException e) {
                throw new BizException(ResultCode.USERNAME_OR_PASSWORD_ERROR);
            }
        }
        return Result.success(userService.getById(id).getUserName());
    }

    @GetMapping("/unAuth")
    void unAuth() {
        throw new BizException(ResultCode.USER_ACCESS_UNAUTHORIZED);
    }

    @ApiOperation(value = "用户登出")
    @GetMapping("/logout")
    void logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

    @RequiresRoles({"admin"})
    @GetMapping
    @ApiOperation(value = "查询用户")
    IPage<UserVo> getUserList(@Validated UserListDto userListDto) {
        return userService.getUserList(userListDto);
    }

    @RequiresRoles({"admin"})
    @PostMapping
    @ApiOperation(value = "新增用户")
    void addUser(@Validated UserAddDto userAddDto) {
        CheckEntityUtil.isNotNullById(userAddDto.getId(), userService, ResultCode.USER_ACCOUNT_EXIST);
        CheckEntityUtil.isNullById(userAddDto.getRoleId(), roleService, ResultCode.ROLE_NOT_EXIST);

        User user = new User();
        userAddDto.convertToEntity(user);
        userService.save(user);
    }

    @RequiresRoles({"admin"})
    @PutMapping
    @ApiOperation(value = "修改用户")
    void upUser(@Validated UserUpdDto userUpdDto) {
        User user = CheckEntityUtil.isNullById(userUpdDto.getId(), userService, ResultCode.USER_ACCOUNT_NOT_EXIST);
        CheckEntityUtil.isNullById(userUpdDto.getRoleId(), roleService, ResultCode.ROLE_NOT_EXIST);

        userUpdDto.convertToEntity(user);
        userService.updateById(user);
    }


    @RequiresAuthentication
    @PutMapping("/password/{id}/{password}")
    @ApiOperation(value = "用户修改个人密码")
    void upUserPassword(@NotNull @PathVariable String id, @NotNull @PathVariable String password) {
        User user = CheckEntityUtil.isNullById(id, userService, ResultCode.USER_ACCOUNT_NOT_EXIST);

        if (user.getPassword().equals(password)) {
            throw new BizException(ResultCode.USER_OLD_PASSWORD_EQUAL_NEW_PASSWORD);
        }
        user.setPassword(password);
        userService.updateById(user);
        //修改密码后退出登录
        logout();
    }

    @RequiresRoles({"admin"})
    @DeleteMapping("/{id}")
    @ApiOperation(value = "禁用用户")
    void delUser(@NotNull @PathVariable String id) {
        CheckEntityUtil.isNullById(id, userService, ResultCode.USER_ACCOUNT_NOT_EXIST);
        userService.removeById(id);
    }
}
